home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / text.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  8KB  |  325 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <X11/StringDefs.h>
  16. #include <X11/Intrinsic.h>
  17. #include <X11/Shell.h>
  18. #include <X11/Xaw/Dialog.h>
  19. #include <X11/Xaw/Command.h>
  20. #include <X11/Xaw/Toggle.h>
  21. #include <X11/Xaw/Form.h>
  22. #include <X11/Xaw/Label.h>
  23. #include <X11/Xaw/AsciiText.h>
  24. #include <X11/Xaw/Text.h>
  25. #include "misc.h"
  26. #include "text.h"
  27.  
  28. typedef struct {
  29.     Widget        shell, widget, okButton;
  30.     TextPromptInfo    *prmps;
  31.     XtCallbackProc    okFunc, cancelFunc;
  32.     void        *closure;
  33.     char        *name;
  34.     Widget        form, curFocus;
  35.     int        current;
  36. } LocalInfo;
  37.  
  38. typedef struct tup {
  39.     Widget        parent, shell;
  40.     LocalInfo    *info;
  41.     char        *name;
  42.     struct tup    *next;
  43. } textUpList;
  44.  
  45. static textUpList    *head = NULL;
  46.  
  47. static void removeTextUp(char *nm)
  48. {
  49.     textUpList    *cur = head, **pp = &head;
  50.  
  51.     while (cur != NULL && cur->name != nm) {
  52.         pp = &cur->next;
  53.         cur = cur->next;
  54.     }
  55.     if (cur != NULL) {
  56.         *pp = cur->next;
  57.         XtFree((XtPointer)cur);
  58.     }
  59. }
  60.  
  61. static void cancelCallback(Widget junkW, XtPointer lArg, XtPointer junk)
  62. {
  63.     LocalInfo    *l = (LocalInfo *)lArg;
  64.     XtCallbackProc    uf = l->cancelFunc;
  65.     Widget        w  = l->widget;
  66.     void        *c = l->closure;
  67.     TextPromptInfo    *p = l->prmps;
  68.  
  69.     removeTextUp(l->name);
  70.  
  71.     XtDestroyWidget(l->shell);
  72.     XtFree((XtPointer)l);
  73.  
  74.     if (uf != NULL)
  75.         uf(w, c, (XtPointer)p);
  76. }
  77.  
  78. static void okCallback(Widget junkW, XtPointer lArg, XtPointer junk)
  79. {
  80.     LocalInfo    *l = (LocalInfo *)lArg;
  81.     XtCallbackProc    uf = l->okFunc;
  82.     Widget        w  = l->widget;
  83.     void        *c = l->closure;
  84.     TextPromptInfo    *p = l->prmps;
  85.     int        i;
  86.  
  87.     for (i = 0; i < p->nprompt; i++)
  88.         XtVaGetValues(p->prompts[i].w, XtNstring, &p->prompts[i].rstr, NULL);
  89.  
  90.     if (uf != NULL)
  91.         uf(w, c, (XtPointer)p);
  92.  
  93.     removeTextUp(l->name);
  94.  
  95.     XtDestroyWidget(l->shell);
  96.     XtFree((XtPointer)l);
  97. }
  98.  
  99. static void setFocus(LocalInfo *l)
  100. {
  101.     Widget    w = l->prmps->prompts[l->current].w;
  102.  
  103.     if (w != l->curFocus) {
  104.         if (l->curFocus != None)
  105.             XtVaSetValues(l->curFocus, XtNdisplayCaret, False, NULL);
  106.  
  107.         XtSetKeyboardFocus(l->form, w);
  108.         XtVaSetValues(w, XtNdisplayCaret, True, NULL);
  109.         l->curFocus = w;
  110.     }
  111. }
  112.  
  113. static void prevField(Widget w, XEvent *event, String *prms, Cardinal *nprms)
  114. {
  115.     Widget        shell = GetShell(w);
  116.     textUpList    *cur;
  117.     LocalInfo    *l;
  118.  
  119.     for (cur = head; cur != NULL; cur = cur->next)
  120.         if (cur->shell == shell)
  121.             break;
  122.     if (cur == NULL)
  123.         return;
  124.     
  125.     l = cur->info;
  126.  
  127.     if (l->current == 0) {
  128.         l->current = l->prmps->nprompt;
  129.     }
  130.     l->current--;
  131.     setFocus(l);
  132. }
  133. static void nextField(Widget w, XEvent *event, String *prms, Cardinal *nprms)
  134. {
  135.     Widget        shell = GetShell(w);
  136.     textUpList    *cur;
  137.     LocalInfo    *l;
  138.  
  139.     for (cur = head; cur != NULL; cur = cur->next)
  140.         if (cur->shell == shell)
  141.             break;
  142.     if (cur == NULL)
  143.         return;
  144.  
  145.     l = cur->info;
  146.  
  147.     if (l->prmps->nprompt == ++l->current) {
  148.         if (*nprms != 0 && strcmp(prms[0], "True") == 0) {
  149.             XtCallActionProc(l->okButton, "set", NULL, NULL, 0);
  150.             XtCallActionProc(l->okButton, "notify", NULL, NULL, 0);
  151.             /*
  152.             okCallback(l->okButton, (XtPointer)l, NULL);
  153.             */
  154.         } else {
  155.             l->current = 0;
  156.             setFocus(l);
  157.         }
  158.     } else {
  159.         setFocus(l);
  160.     }
  161. }
  162.  
  163. static void buttonCB(Widget w, LocalInfo *l, XButtonEvent *event, XtPointer junk)
  164. {
  165.     int    i;
  166.  
  167.     for (i = 0; i < l->prmps->nprompt; i++)
  168.         if (l->prmps->prompts[i].w == w)
  169.             break;
  170.     l->current = i;
  171.  
  172.     setFocus(l);
  173. }
  174.  
  175. void TextPrompt(Widget w, char *name, TextPromptInfo *prompt, 
  176.         XtCallbackProc okProc, XtCallbackProc nokProc, void *data)
  177. {
  178.     int        i;
  179.     Position    x, y;
  180.     static String    textAccelerators = "#override\n\
  181.                 <Key>Return: set() notify() unset()\n\
  182.                 <Key>Linefeed: set() notify() unset()";
  183.     static String    textTranslations = "#override\n\
  184.                      Shift<Key>Tab: prev-typin(False)\n\
  185.                      <Key>Tab: next-typin(False)\n\
  186.                      <Key>Return: next-typin(True)\n\
  187.                      <Key>Linefeed: next-typin(True)\n\
  188.                      Ctrl<Key>M: next-typin(True)\n\
  189.                      Ctrl<Key>J: next-typin(True)\n";
  190.     static XtActionsRec     act[2] = {
  191.                 { "next-typin", (XtActionProc)nextField },
  192.                 { "prev-typin", (XtActionProc)prevField },
  193.             };
  194.     static XtTranslations    trans = None, toglt = None;
  195.     static XtAccelerators    accel;
  196.     Widget        labelList[64];
  197.     Widget        shell, form, title, text = None, last, label;
  198.     Widget        okButton, cancelButton, wshell;
  199.     LocalInfo    *l;
  200.     textUpList    *cur;
  201.     Dimension    width, maxWidth = 0;
  202.  
  203.     for (cur = head; cur != NULL; cur = cur->next) {
  204.         if (strcmp(cur->name, name) == 0 && cur->parent == w) {
  205.             XtPopup(cur->shell, XtGrabNone);
  206.             return;
  207.         }
  208.     }
  209.  
  210.     cur = XtNew(textUpList);
  211.     cur->next = head;
  212.     cur->name = name;
  213.     cur->parent = w;
  214.     head = cur;
  215.  
  216.     l = XtNew(LocalInfo);
  217.     l->name = cur->name;
  218.  
  219.     cur->info = l;
  220.  
  221.     if (trans == None) {
  222.         XtAppAddActions(XtWidgetToApplicationContext(w), act, 2);
  223.         trans = XtParseTranslationTable(textTranslations);
  224.         accel = XtParseAcceleratorTable(textAccelerators);
  225.         toglt = XtParseTranslationTable("<BtnDown>,<BtnUp>: set() notify()");
  226.     }
  227.  
  228.     wshell = GetShell(w);
  229.     if (!XtIsRealized(wshell)) 
  230.         wshell = GetToplevel(w);
  231.     XtVaGetValues(wshell, XtNx, &x, XtNy, &y, NULL);
  232.  
  233.     shell = XtVaCreatePopupShell(name == NULL ? "popup-dialog" : name,
  234.             transientShellWidgetClass, wshell,
  235.             XtNx, x + 24,
  236.             XtNy, y + 24,
  237.             NULL);
  238.     cur->shell = shell;
  239.  
  240.     form = XtVaCreateManagedWidget("popup-dialog-form",
  241.                 formWidgetClass, shell,
  242.                 XtNborderWidth, 0,
  243.                 NULL);
  244.  
  245.     title = XtVaCreateManagedWidget("title",
  246.                 labelWidgetClass, form,
  247.                 XtNlabel, prompt->title, 
  248.                 XtNborderWidth, 0,
  249.                 NULL);
  250.  
  251.     last = title;
  252.     for (i = 0; i < prompt->nprompt; i++) {
  253.         label = XtVaCreateManagedWidget("label",
  254.                 labelWidgetClass, form,
  255.                 XtNfromVert, last,
  256.                 XtNlabel, prompt->prompts[i].prompt, 
  257.                 XtNborderWidth, 0,
  258.                 XtNleft, XtChainLeft,
  259.                 XtNright, XtChainLeft,
  260.                 NULL);
  261.         labelList[i] = label;
  262.         XtVaGetValues(label, XtNwidth, &width, NULL);
  263.         if (width > maxWidth)
  264.             maxWidth = width;
  265.  
  266.         text = XtVaCreateManagedWidget("text",
  267.                 asciiTextWidgetClass, form,
  268.                 XtNfromHoriz, label,
  269.                 XtNfromVert, last,
  270.                 XtNeditType, XawtextEdit,
  271.                 XtNwrap, XawtextWrapNever,
  272.                 XtNresize, XawtextResizeWidth,
  273.                 XtNtranslations, trans,
  274.                 XtNlength, prompt->prompts[i].len,
  275.                 XtNstring, prompt->prompts[i].str,
  276.                 XtNinsertPosition, strlen(prompt->prompts[i].str),
  277.                 XtNleft, XtChainLeft,
  278.                 XtNdisplayCaret, False,
  279.                 NULL);
  280.         XtAddEventHandler(text, ButtonPressMask, False, (XtEventHandler)buttonCB, (XtPointer)l);
  281.         
  282.         last = text;
  283.         prompt->prompts[i].w = text;
  284.     }
  285.     for (i = 0; i < prompt->nprompt; i++)
  286.         XtVaSetValues(labelList[i], XtNwidth, maxWidth, NULL);
  287.  
  288.     okButton = XtVaCreateManagedWidget("ok",
  289.                 commandWidgetClass, form,
  290.                 XtNfromVert, last,
  291.                 XtNaccelerators, accel,
  292.                 NULL);
  293.     cancelButton = XtVaCreateManagedWidget("cancel",
  294.                 commandWidgetClass, form,
  295.                 XtNfromVert, last,
  296.                 XtNfromHoriz, okButton,
  297.                 NULL);
  298.  
  299.  
  300.     l->widget     = w;
  301.     l->curFocus   = None;
  302.     l->shell      = shell;
  303.     l->prmps      = prompt;
  304.     l->closure    = data;
  305.     l->okFunc     = okProc;
  306.     l->current    = 0;
  307.     l->cancelFunc = nokProc;
  308.     l->okButton   = okButton;
  309.     l->form       = form;
  310.  
  311. #if 0
  312.     if (prompt->nprompt == 1) {
  313.         XtSetKeyboardFocus(form, text);
  314.         XtInstallAccelerators(text, okButton);
  315.     }
  316. #endif
  317.     setFocus(l);
  318.     
  319.     XtAddCallback(okButton, XtNcallback, okCallback, (XtPointer)l);
  320.     XtAddCallback(cancelButton, XtNcallback, cancelCallback, (XtPointer)l);
  321.         AddDestroyCallback(shell, (void (*)(Widget, void *, XEvent *))cancelCallback, (XtPointer)l);
  322.  
  323.     XtPopup(shell, XtGrabNone);
  324. }
  325.